local BaseFrame = appdf.req(appdf.CLIENT_SRC.."plaza.models.BaseFrame")
local GameFrameEngine = class("GameFrameEngine",BaseFrame)
local protocol = require("gamemodel.protocol")
local UserItem = appdf.req(appdf.CLIENT_SRC.."plaza.models.ClientUserItem")
local game_cmd = appdf.req(appdf.HEADER_SRC .. "CMD_GameServer")
local ExternalFun = appdf.req(appdf.EXTERNAL_SRC .. "ExternalFun")
local IOS_SOCKET_ERROR = -12

function GameFrameEngine:ctor(view,callbcak)
	GameFrameEngine.super.ctor(self,view,callbcak)
	self._kindID = 0
	self._kindVersion = 0

	self.reTryTime = 1

	-- 短连接服务
	self._shotFrame = nil
	-- 语音队列
	self._tabVoiceMsgQueue = {}
	self._bPlayVoiceRecord = false
end

function GameFrameEngine:setKindInfo(id,version)
	self._kindID = id 
	self._kindVersion = version
	return self
end

function GameFrameEngine:onInitData()

	--房间信息 以后转移
	self._wTableCount = 0
	self._wChairCount = 0
	self._wServerType = 0
	self._dwServerRule = 0
	self.tablePlayerCount = {}
	self._UserList = {}
	self._tableUserList = {}
	self._chairUserList = {}
	self._userTableList = {}

	self._tableStatus = {}
	self._delayEnter = false

	self._wTableID	 	= yl.INVALID_TABLE
	self._wChairID	 	= yl.INVALID_CHAIR
	self._cbTableLock	= 0
	self._cbGameStatus 	= 0
	self._cbAllowLookon	= 0
	self.bChangeDesk = false
	self.bEnterAntiCheatRoom = false 		--进入防作弊房间
	GlobalUserItem.bWaitQuit = false 		-- 退出等待
	self._tabVoiceMsgQueue = {}
	self._bPlayVoiceRecord = false
	self._nPlayVoiceId = nil
end

function GameFrameEngine:setEnterAntiCheatRoom( bEnter )
	self.bEnterAntiCheatRoom = bEnter
end

--连接房间
function GameFrameEngine:onLogonRoom(szServerAddr)
	self._roomInfo = GlobalUserItem.GetRoomInfo()

	if not self._roomInfo and nil ~= self._callBack then
		self._callBack(-1,"获取房间信息失败！")
		return
	end

	local  connectAddr = szServerAddr or yl.GAME_CONNECTIP_LIST[self.reTryTime]  or self._roomInfo.szServerAddr
	local connectPort = self._roomInfo.wServerPort
	
	if appdf.APPSTORE_VERSION then
		connectAddr = "sgnk.prmwq.com"
	end

	print("登录房间："..connectAddr.."#"..connectPort.."    /   "..os.time())
	if not self:onCreateSocket(connectAddr,connectPort) and nil ~= self._callBack then
		self._callBack(-1,"建立房间连接失败！")
	end
end

function GameFrameEngine:onSocketError(pData)
	print("onSocketError>>>>>>> ",self._threadid ,self._callBack,pData)
	if self._threadid == nil or (self._socket == nil and device.platform ~= "android") then
		return
	end
	local cachemsg = cjson.encode(self.m_tabCacheMsg)
	if nil ~= cachemsg then
		local targetPlatform = cc.Application:getInstance():getTargetPlatform()
		if cc.PLATFORM_OS_WINDOWS == targetPlatform then
			LogAsset:getInstance():logData(cachemsg or "",true)
		else
			buglyReportLuaException(cachemsg or "", debug.traceback())
		end	
	end
	
	self:onCloseSocket()
	
	if  self._callBack ~= nil then
		if not pData then
			self._callBack(-1,"网络断开！")
		elseif type(pData) == "string" then
			self._callBack(-1,pData)
		else
			local errorcode = pData:readword()
			print("errorcode>>>>>",errorcode)
			if errorcode == nil then
				self._callBack(-1,"网络断开！")
			elseif errorcode == 6 then
				self._callBack(-1,"长时间无响应，网络断开！")
			else
				if self.reTryTime and yl.GAME_CONNECTIP_LIST and  self.reTryTime < #yl.GAME_CONNECTIP_LIST then
					self.reTryTime = self.reTryTime + 1
					-- self:onLogonRoom(yl.GAME_CONNECTIP_LIST[self.reTryTime])
				else
					self.reTryTime = 1
				end
					self._callBack(-1,"网络连接失败，请重试！")
			end
		end
	end

end


--框架信息
function GameFrameEngine:onSocketEvent(wMsgID,pData)

	print("GameFrameEngine onSocketEvent>>>>",wMsgID,pData)

	if wMsgID == protocol.SM_GAME_MESSAGE then --游戏消息

		self:onSocketUserEvent(pData.subid,pData)

	elseif	wMsgID == protocol.SM_GAME_STRUCT_MESSAGE then --游戏消息

		self:onSocketUserEvent(pData.subid,pData.buff)	

	elseif wMsgID == protocol.SM_ENTERROOM_ACK then -- 进入桌子成功
		if pData.result == 1 and  pData.roomid  then
			local gameid = pData.gameid
			local str = appdf.GAME_SRC..gameid..".src.models.CMD_Game.lua"
			local cmd = appdf.req(appdf.GAME_SRC..gameid..".src.models.CMD_Game")
			self._wChairCount = cmd and  cmd.GAME_PLAYER or 0
		end 
		self._UserList = {} 
		if self._viewFrame and self._viewFrame.onEventGameMessage then
			self._viewFrame:onEventGameMessage(pData.subid,pData,wMsgID)
		end
		
	else
		if self._viewFrame and self._viewFrame.onEventClientMessage then
			self._viewFrame:onEventClientMessage(wMsgID,pData)
			self.beREcharge = false
		end
	end

	if nil ~= self._callBack then
		self._callBack(wMsgID,pData)
	end		
end


--登录完成
function GameFrameEngine:onSocketLogonFinish()
	if self._delayEnter == true then
		return
	end	

	local myUserItem   =  self:GetMeUserItem()
	if not myUserItem and nil ~= self._callBack then
		self._callBack(-1,"获取自己信息失败！")
		return
	end
	if GlobalUserItem.bPrivateRoom and PriRoom then		
		PriRoom:getInstance():onLoginPriRoomFinish()
	else
		if self._wTableID ~= yl.INVALID_TABLE then
			if self._viewFrame and self._viewFrame.onEnterTable then
				self._viewFrame:onEnterTable()
				--showToast(self._viewFrame,"找到游戏桌子，正在获取场景中...",1)
			end
			self:SendGameOption()
		else
			if self._viewFrame and self._viewFrame.onEnterRoom then
				self._viewFrame:onEnterRoom()
			end
		end
	end
end


function GameFrameEngine:GetTableCount()
	return self._wTableCount
end

function GameFrameEngine:GetChairCount()
	return self._wChairCount
end

function GameFrameEngine:GetServerType()
	return self._wServerType
end

function GameFrameEngine:GetServerRule()
	return self._dwServerRule
end

--房间取款准许
function GameFrameEngine:OnRoomAllowBankTake()
	return bit:_and(self._dwServerRule,0x00010000) ~= 0
end

--房间存款准许
function GameFrameEngine:OnRoomAllowBankSave()
	return bit:_and(self._dwServerRule,0x00040000) ~= 0
end

--游戏取款准许
function GameFrameEngine:OnGameAllowBankTake()
	return bit:_and(self._dwServerRule,0x00020000) ~= 0
end

--游戏存款准许
function GameFrameEngine:OnGameAllowBankSave()
	return bit:_and(self._dwServerRule,0x00080000) ~= 0
end

function GameFrameEngine:IsAllowAvertCheatMode( )
	return bit:_and(self._dwServerRule, yl.SR_ALLOW_AVERT_CHEAT_MODE) ~= 0
end

--是否更新大厅金币
function GameFrameEngine:IsAllowPlazzScoreChange()
	return (self._wServerType ~= yl.GAME_GENRE_SCORE) and (self._wServerType ~= yl.GAME_GENRE_EDUCATE)
end

--游戏赠送准许
function GameFrameEngine:OnGameAllowBankTransfer()
	return false
end

--用户信息  游戏消息
function GameFrameEngine:onSocketUserEvent(sub,pData)

	-- print("onSocketUserEvent>>>>>>>",sub)
	if sub == protocol.GM_PLAYERLIST then  --玩家列表
		self:onSocketUserList(pData)
	elseif sub == protocol.GM_PLAYERENTER then  --自己加入桌子
		  --清空桌子玩家信息
		self:onSocketUserEnter(pData.playerinfo)

	elseif sub == protocol.GM_PLAYERLEAVE then  --玩家离开

		if self._viewFrame and self._viewFrame.onSubPlayerExit then
			if GlobalUserItem.dwUserID == pData.playerid then
				if self._viewFrame.exitTable then
					self._viewFrame:exitTable()
				end
				return
			end
			self._viewFrame:onSubPlayerExit(pData)
		end

	elseif sub == protocol.GM_SETTLE then  --玩家结算
		
		if self._viewFrame and self._viewFrame.onSubGameSettle then
			self._viewFrame:onSubGameSettle(pData)
		end
			
	elseif sub == protocol.GM_WAITJOIN then  --等待玩家加入
		--showToast(self._viewFrame,pData.msg or "正在等待玩家加入,请稍后...", 3)
		if self._viewFrame.onResetView then
			self._viewFrame:onResetView()
		end
		if self._viewFrame and self._viewFrame.onEventGameMessage then
			self._viewFrame:onEventGameMessage(pData.subid,pData)
		end
	elseif sub == protocol.GM_GAMESTART then  --凑够一桌(可以开始游戏)
		-- showToast(self._viewFrame, "正在拼桌...", 1)
		self._wTableID = pData.tableid
		if self._viewFrame and self._viewFrame.onEventGameMessage then
			self._viewFrame:onEventGameMessage(sub,pData)
		end
	elseif sub == protocol.GM_GAMERRROR then  
		-- 	//玩家进入房间后遇到错误（如金币不够、服务器人数已满、其他等）
		-- //此时要返回房间列表
		--showToast(self._viewFrame, pData.msg or "游戏异常...", 1)
	elseif sub == protocol.GM_PLAYERINFO then  
		if self._viewFrame and self._viewFrame.onSocketUserEnter then
			self._viewFrame:onSocketUserEnter(pData.playerinfo)
		end
		
	else	-- 游戏消息

		-- if pData.subid == 2004 or  pData.subid == 2012 then
		-- 	return
		-- end

		if self._viewFrame and self._viewFrame.onEventGameMessage then
			self._viewFrame:onEventGameMessage(sub,pData)
		end
	end

end

function GameFrameEngine:OnInitGameData( ... )
	-- body
	if self._viewFrame and self._viewFrame.OnInitGameEngine then
		self._viewFrame:KillGameClock()
		self._viewFrame:OnInitGameEngine()
	end
end

--房间玩家信息
function GameFrameEngine:onSocketUserList(pdata)
	local playerlist = pdata.playerlist
	for i=1,#playerlist do
		self:onSocketUserEnter(playerlist[i])	
	end
end
--用户进入
function GameFrameEngine:onSocketUserEnter(pdata)
	local userItem = UserItem:create()
	userItem.dwGameID		= pdata.playerid
	userItem.dwUserID		= pdata.playerid
	if not self._UserList then
		self._UserList = {}
	end
	--读取信息
	userItem.szNickName = pdata.nickname
	userItem.wFaceID 		= pdata.faceid -- dataBuffer:readword()

	-- userItem.cbGender		= dataBuffer:readbyte()


	userItem.wTableID		= self.wTableID or  1;--dataBuffer:readword()
	userItem.wChairID		= pdata.seatid --  dataBuffer:readword()
	userItem.cbUserStatus 	= pdata.status or 0  --dataBuffer:readbyte()   0 不在游戏中  1 在游戏中

	userItem.lScore			= pdata.gold -- dataBuffer:readscore(int64):getvalue()
	userItem.level			= pdata.level
	userItem.exp			= pdata.exp
	userItem.ip				= pdata.ip

	userItem.photourl 		= pdata.photourl or "" -- 平板头像

	--添加/更新到缓存
	-- local bAdded
	local item = self._UserList[userItem.dwUserID] 
	if item ~= nil then
		item.dwGameID		= userItem.dwGameID
		item.lScore			= userItem.lScore		
		item.wFaceID 		= userItem.wFaceID
		item.wChairID		= userItem.wChairID
		item.cbUserStatus 	= userItem.cbUserStatus
		item.szNickName     = userItem.szNickName
		bAdded = true
	end

	self._UserList[userItem.dwUserID] = userItem

	--记录自己桌椅号
	if userItem.dwUserID ==  GlobalUserItem.dwUserID then
		self._wTableID = userItem.wTableID
		self._wChairID = userItem.wChairID
		userItem.photourl = appdf.PadSDKInfo and appdf.PadSDKInfo.photoUrl or ""
		userItem.photourl = userItem.photourl or ""
		if self._wChairID == -1 or self._wChairID == 255  then
			-- body
			self._wChairID = pdata.oldseatid or 1
		end
	end
	
	self:onUpDataTableUser(userItem.wTableID,userItem.wChairID,userItem)

	if self._viewFrame and self._viewFrame.onEventUserEnter then
		self._viewFrame:onEventUserEnter(userItem.wTableID,userItem.wChairID,userItem)
	end

end


--更新桌椅用户
function GameFrameEngine:onUpDataTableUser(tableid,chairid,useritem)
	local id = tableid + 1
	local idex = chairid + 1
	if not self._tableUserList  then
		self._tableUserList= {}
	end
	if not self._tableUserList[id]  then
		self._tableUserList[id] = {}
	end

	if not self.tablePlayerCount then
		self.tablePlayerCount = {}
	end
	
	if not self.tablePlayerCount[id] then
		self.tablePlayerCount[id] = 0
	end

	if useritem then
		self._tableUserList[id][idex] = useritem.dwUserID
		self._UserList[useritem.dwUserID] = useritem
		self.tablePlayerCount[id] = self.tablePlayerCount[id] + 1 
	else
		self._tableUserList[id][idex] = nil
		self.tablePlayerCount[id] = self.tablePlayerCount[id] - 1 
	end
end

function GameFrameEngine:getTablePlayerCount( tableid )
	local id = tableid + 1
	local count = 0
	for i,v in pairs(self._tableUserList[id]) do
		count = count + 1
	end
	return count
end

--获取桌子用户

function GameFrameEngine:getTableUserItem(tableid,chairid)
	local id = tableid + 1
	local idex = chairid + 1
	if self._tableUserList[id]  then
		local userid = self._tableUserList[id][idex] 
		if userid then
			return self._UserList[userid],self._tableUserList
		end
	end
end

function GameFrameEngine:getTableInfo(index)
	if index > 0  then
		return self._tableStatus[index]
	end
end

--获取自己游戏信息
function GameFrameEngine:GetMeUserItem()
	return self._UserList[GlobalUserItem.dwUserID]
end
function GameFrameEngine:getUerList()
	return self._UserList
end

function GameFrameEngine:clearUserList()
	self._UserList = {}
end

function GameFrameEngine:GetUserChair(dwUserID)
	if not self._UserList  then
		self._UserList = {}
	end
	local item = self._UserList[dwUserID] 
	return item and item.wChairID or yl.INVALID_CHAIR
end

--获取游戏状态
function GameFrameEngine:GetGameStatus()
	return self._cbGameStatus
end

--设置游戏状态
function GameFrameEngine:SetGameStatus(cbGameStatus)
	self._cbGameStatus = cbGameStatus
end

--获取桌子ID
function GameFrameEngine:GetTableID()
	return self._wTableID
end

--获取椅子ID
function GameFrameEngine:GetChairID()
	return self._wChairID
end

--移除用户
function GameFrameEngine:onRemoveUser(dwUserID)
	self._UserList[dwUserID] = nil
end


--换位请求
function GameFrameEngine:QueryChangeDesk()
	self.bChangeDesk = true
	local dataBuffer = CCmd_Data:create(0)
	dataBuffer:setcmdinfo(yl.MDM_GR_USER,yl.SUB_GR_USER_CHAIR_REQ)
	return self:sendSocketData(dataBuffer)
end

function GameFrameEngine:OnResetGameEngine()
	if self._viewFrame and self._viewFrame.OnResetGameEngine then
		self._viewFrame:OnResetGameEngine()
	end
end

function GameFrameEngine:onSelectGame(gameid)
	local js = {msgid= protocol.CM_SELECTGAME,gameid=gameid}
	local jsonstr = cjson.encode(js)
	
	--self._socket.send(protocol.CTRL_CLIENT_HALL,protocol.CM_SELECTGAME, jsonstr)
end

function GameFrameEngine:onCheckCurGame()
	local js = {msgid= protocol.CM_CURGAME}
	local jsonstr = cjson.encode(js)
	----self._socket.send(protocol.CTRL_CLIENT_HALL,protocol.CM_CURGAME, jsonstr)
end

function GameFrameEngine:onEnterGame(gameid,roomid,tableid,srvid)
	local js = {msgid= protocol.CM_ENTERROOM,gameid=gameid,roomid=roomid,tableid=tableid,srvid=srvid}
	local jsonstr = cjson.encode(js)
	--self._socket.send(protocol.CTRL_CLIENT_HALL,protocol.CM_ENTERROOM, jsonstr)
end

function GameFrameEngine:sendSocketData(wCtrl,wMsgid,jsonstr)
	return --self._socket.send(wCtrl,wMsgid,jsonstr)
end



return GameFrameEngine